package com.gree.elasticsearch.service;

import com.gree.elasticsearch.dao.FoolRepository;
import com.gree.elasticsearch.domain.Bar;
import com.gree.elasticsearch.domain.Foo;
import org.hibernate.annotations.ManyToAny;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.Optional;

@Service
public class DefaultFooService  {

    private Logger log = LoggerFactory.getLogger(DefaultFooService.class.getName());

    @Autowired
    private FoolRepository foolRepository;

    @Autowired
    private DefaultBarService barService;

    @Autowired
    private BoolService boolService;

    @Autowired
    private JdbcTemplate jdbcTemplate;

    public Foo getFoo(String fooName) {
        log.info("get foo. parameter fooName is {}", fooName);
        return null;
    }

    public Foo getFoo(String fooName, String barName) {
        log.info("get foo. parameter fooName is {}. barName is {}", fooName, barName);
        return null;
    }

    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})
    public void insertFoo(Foo foo) {
        String currentThreadName = Thread.currentThread().getName();
        Foo foo1 = new Foo(currentThreadName);
        Foo foo2 = new Foo(currentThreadName);
        Foo foo3 = new Foo(currentThreadName);
        foolRepository.save(foo1);
        foolRepository.save(foo2);
        foolRepository.save(foo3);
        log.debug("save three foo items");
        try {
            barService.createBar();
        } catch (Exception e) {
            log.debug("barService createBar happend exception. exception message is {}", e.getMessage());
        }
    }

    @Transactional(propagation = Propagation.NESTED)
    public void createFooByJdbTemplate() {
        jdbcTemplate.execute("insert into foo(name) values('zhangsan')");
        jdbcTemplate.execute("insert into foo(name) values('zhangsan')");
        jdbcTemplate.execute("insert into foo(name) values('zhangsan')");
        barService.createBarByTemplate();
        throw new RuntimeException("out transaction throw run time exception");
    }

    @Transactional
    public void updateFoo(Foo foo) {
        log.info("update foo. parameter foo is ", foo);
    }

    @Transactional(propagation = Propagation.REQUIRED)
    public Foo findById(Integer id) {
        Optional<Foo> fooOptional = foolRepository.findById(id);
        return fooOptional.get();
    }
}